package cc.smarnet.caihou.gftest;

import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;

import android.Manifest;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.hardware.usb.UsbManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.TextView;

import com.smart.command.EscCommand;
import com.smart.command.LabelCommand;

import java.util.ArrayList;
import java.util.Vector;

import cc.smarnet.caihou.R;
import cc.smarnet.caihou.bluetooth.BluetoothDeviceList;

import cc.smarnet.caihou.bluetooth.Constant;
import cc.smarnet.caihou.bluetooth.DeviceConnFactoryManager;
import cc.smarnet.caihou.bluetooth.ThreadPool;
import cc.smarnet.caihou.bluetooth.Utils;

/**
 *
 * 蓝牙连接的测试页面
 */
public class BlueToothTestMainActivity extends AppCompatActivity {
    private static final String TAG = "BlueToothTestMainActivity";
    ArrayList<String> per = new ArrayList<>();
    private UsbManager usbManager;
    private int counts;
    private static final int REQUEST_CODE = 0x004;

    private Bitmap bitmap = Bitmap.createBitmap(660, 40, Bitmap.Config.ARGB_8888);

    /**
     * Connection status disconnected
     */
    private static final int CONN_STATE_DISCONN = 0x007;
    /**
     * Use printer command error
     */
    private static final int PRINTER_COMMAND_ERROR = 0x008;

    private static final int CONN_MOST_DEVICES = 0x11;
    private static final int CONN_PRINTER = 0x12;
    private PendingIntent mPermissionIntent;
    private String[] permissions = {
            Manifest.permission.ACCESS_FINE_LOCATION,
            Manifest.permission.ACCESS_COARSE_LOCATION,
            Manifest.permission.BLUETOOTH
    };
    private String usbName;
    private TextView tvConnState;
    private ThreadPool threadPool;

    private int id = 0;
    private int printcount = 0;
    private boolean continuityprint = false;

    // private KeepConn keepConn;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.e(TAG, "onCreate()");
        setContentView(R.layout.activity_bluetooth_test_main);
        usbManager = (UsbManager) getSystemService(Context.USB_SERVICE);
        checkPermission();
        requestPermission();
        tvConnState = (TextView) findViewById(R.id.tv_connState);
    }

    @Override
    protected void onStart() {
        super.onStart();
        IntentFilter filter = new IntentFilter();
        filter.addAction(DeviceConnFactoryManager.ACTION_QUERY_PRINTER_STATE);
        filter.addAction(DeviceConnFactoryManager.ACTION_CONN_STATE);
        registerReceiver(receiver, filter);
    }

    private void checkPermission() {
        for (String permission : permissions) {
            if (PackageManager.PERMISSION_GRANTED != ContextCompat.checkSelfPermission(this, permission)) {
                per.add(permission);
            }
        }
    }

    private void requestPermission() {
        if (per.size() > 0) {
            String[] p = new String[per.size()];
            ActivityCompat.requestPermissions(this, per.toArray(p), REQUEST_CODE);
        }
    }

    /**
     * Bluetooth connect
     */
    public void btnBluetoothConn(View view) {
        startActivityForResult(new Intent(this, BluetoothDeviceList.class), Constant.BLUETOOTH_REQUEST_CODE);
    }



    /**
     * Print label
     */
    public void btnLabelPrint(View view) {
        threadPool = ThreadPool.getInstantiation();
        threadPool.addTask(() -> {
            if (!isConnected()) {
                mHandler.obtainMessage(CONN_PRINTER).sendToTarget();
                return;
            }
            sendLabel();
        });
    }

    /**
     * Disconnect
     */
    public void btnDisConn(View view) {
        if (!isConnected()) {
            Utils.toast(this, getString(R.string.str_cann_printer));
            return;
        }
        mHandler.obtainMessage(CONN_STATE_DISCONN).sendToTarget();
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == RESULT_OK) {
            switch (requestCode) {

                case Constant.BLUETOOTH_REQUEST_CODE: {
                    closeport();
                    //Get bluetoot mac address
                    String macAddress = data.getStringExtra(BluetoothDeviceList.EXTRA_DEVICE_ADDRESS);
                    //Init DeviceConnFactoryManager
                    new DeviceConnFactoryManager.Build()
                            .setConnectMethod(DeviceConnFactoryManager.CONN_METHOD.BLUETOOTH)
                            //Set bluetooth mac address
                            .setMacAddress(macAddress)
                            .build();
                    //Open port
                    threadPool = ThreadPool.getInstantiation();
                    threadPool.addTask(() -> DeviceConnFactoryManager.getDeviceConnFactoryManager().openPort());

                    break;
                }
                default:
                    break;
            }
        }
    }

    /**
     * Reconnection recycles the last connected object to avoid memory leakage
     */
    private void closeport() {
        if (isConnected()) {
//            DeviceConnFactoryManager.getDeviceConnFactoryManagers()[id].reader.cancel();
            DeviceConnFactoryManager.getDeviceConnFactoryManager().closePort();
        }
    }

    /**
     * Print label
     */
    void sendLabel() {
        LabelCommand tsc = new LabelCommand();
        // Set the label size according to the actual size
        tsc.addSize(80, 50);
        // Set the label gap according to the actual size. If it is no gap paper, set it to 0
        tsc.addGap(2);
        // Set print direction
        tsc.addDirection(LabelCommand.DIRECTION.BACKWARD, LabelCommand.MIRROR.NORMAL);
        // Turn on Printing with response for continuous printing
        tsc.addQueryPrinterStatus(LabelCommand.RESPONSE_MODE.ON);
        // Set origin coordinates
        tsc.addReference(0, 0);
        // Tearing mode on
        tsc.addTear(EscCommand.ENABLE.ON);
        // Clear print buffer
        tsc.addCls();
        // Draw simplified Chinese
//        tsc.addText(10, 0, LabelCommand.FONTTYPE.SIMPLIFIED_CHINESE, LabelCommand.ROTATION.ROTATION_0, LabelCommand.FONTMUL.MUL_1, LabelCommand.FONTMUL.MUL_1,
//                "Welcome to use SMARNET printer");
        // Draw a picture
//        Bitmap b = BitmapFactory.decodeResource(getResources(), R.drawable.picture);
        Bitmap b = BitmapFactory.decodeResource(getResources(), R.drawable.xdnylogo);
        tsc.addBitmap(5, 30, -1, 3.7f, LabelCommand.BITMAP_MODE.OVERWRITE, 400, b);
        tsc.addBar(5, 120, 300, 1);

        tsc.addText(20, 135, LabelCommand.FONTTYPE.SIMPLIFIED_CHINESE, LabelCommand.ROTATION.ROTATION_0, LabelCommand.FONTMUL.MUL_1, LabelCommand.FONTMUL.MUL_1,
                "品种：粉红雪山");
        tsc.addText(20, 175, LabelCommand.FONTTYPE.SIMPLIFIED_CHINESE, LabelCommand.ROTATION.ROTATION_0, LabelCommand.FONTMUL.MUL_1, LabelCommand.FONTMUL.MUL_1,
                "产地：A-2");
        tsc.addText(20, 210, LabelCommand.FONTTYPE.SIMPLIFIED_CHINESE, LabelCommand.ROTATION.ROTATION_0, LabelCommand.FONTMUL.MUL_1, LabelCommand.FONTMUL.MUL_1,
                "规格：10枝");

        tsc.addText(200, 255, LabelCommand.FONTTYPE.SIMPLIFIED_CHINESE, LabelCommand.ROTATION.ROTATION_0, LabelCommand.FONTMUL.MUL_1, LabelCommand.FONTMUL.MUL_1,
                "包装员：张雪红");
        tsc.addText(200, 295, LabelCommand.FONTTYPE.SIMPLIFIED_CHINESE, LabelCommand.ROTATION.ROTATION_0, LabelCommand.FONTMUL.MUL_1, LabelCommand.FONTMUL.MUL_1,
                "长度：55 cm");
        tsc.addText(200, 335, LabelCommand.FONTTYPE.SIMPLIFIED_CHINESE, LabelCommand.ROTATION.ROTATION_0, LabelCommand.FONTMUL.MUL_1, LabelCommand.FONTMUL.MUL_1,
                "时间：2021-10-22 11:30:33");

        tsc.addQRCode(370, 40, LabelCommand.EEC.LEVEL_L, 7, LabelCommand.ROTATION.ROTATION_0, "1451015293279653890");
        tsc.addText(340, 200, LabelCommand.FONTTYPE.SIMPLIFIED_CHINESE, LabelCommand.ROTATION.ROTATION_0, LabelCommand.FONTMUL.MUL_1, LabelCommand.FONTMUL.MUL_1,
                "1451015293279653890");

//        tsc.addQRCode(390, 240, LabelCommand.EEC.LEVEL_L, 3, LabelCommand.ROTATION.ROTATION_0, "http://www.ythxdny.com:3001/traceSource?sid=1450738676095504385");
//        tsc.addText(380, 342, LabelCommand.FONTTYPE.SIMPLIFIED_CHINESE, LabelCommand.ROTATION.ROTATION_0, LabelCommand.FONTMUL.MUL_1, LabelCommand.FONTMUL.MUL_1,
//                "产品扫一扫");
        tsc.addQRCode(20, 250, LabelCommand.EEC.LEVEL_L, 3, LabelCommand.ROTATION.ROTATION_0, "http://www.ythxdny.com:3001/traceSource?sid=1450738676095504385");
        tsc.addText(10, 352, LabelCommand.FONTTYPE.SIMPLIFIED_CHINESE, LabelCommand.ROTATION.ROTATION_0, LabelCommand.FONTMUL.MUL_1, LabelCommand.FONTMUL.MUL_1,
                "产品扫一扫");

//        tsc.add1DBarcode(10, 250, LabelCommand.BARCODETYPE.CODE128, 100, LabelCommand.READABEL.EANBEL, LabelCommand.ROTATION.ROTATION_0, "SMARNET");
        // print label
        tsc.addPrint(1, 1);
        // Buzzer sounds after label printing
        tsc.addSound(2, 100);
        tsc.addCashdrwer(LabelCommand.FOOT.F5, 255, 255);
        Vector<Byte> datas = tsc.getCommand();
        // send data
        DeviceConnFactoryManager.getDeviceConnFactoryManager().sendDataImmediately(datas);
    }

    private BroadcastReceiver receiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            switch (action) {
                case DeviceConnFactoryManager.ACTION_CONN_STATE:
                    int state = intent.getIntExtra(DeviceConnFactoryManager.STATE, -1);
                    int deviceId = intent.getIntExtra(DeviceConnFactoryManager.DEVICE_ID, -1);
                    switch (state) {
                        case DeviceConnFactoryManager.CONN_STATE_DISCONNECT:
                            if (id == deviceId) {
                                tvConnState.setText(getString(R.string.str_conn_state_disconnect));
                            }
                            break;
                        case DeviceConnFactoryManager.CONN_STATE_CONNECTING:
                            tvConnState.setText(getString(R.string.str_conn_state_connecting));
                            break;
                        case DeviceConnFactoryManager.CONN_STATE_CONNECTED:
                            tvConnState.setText(getString(R.string.str_conn_state_connected) + "\n" + getConnDeviceInfo());
                            break;
                        case DeviceConnFactoryManager.CONN_STATE_FAILED:
                            Utils.toast(BlueToothTestMainActivity.this, getString(R.string.str_conn_fail));
                            //wificonn=false;
                            tvConnState.setText(getString(R.string.str_conn_state_disconnect));
                            break;
                        default:
                            break;
                    }
                    break;
                case DeviceConnFactoryManager.ACTION_QUERY_PRINTER_STATE:
                    if (counts >= 0) {
                        if (continuityprint) {
                            printcount++;
                            Utils.toast(BlueToothTestMainActivity.this, getString(R.string.str_continuityprinter) + " " + printcount);
                        }
                        if (counts != 0) {
//                            sendContinuityPrint();
                        } else {
                            continuityprint = false;
                        }
                    }
                    break;
                default:
                    break;
            }
        }
    };
    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case CONN_STATE_DISCONN:
                    if (isConnected()) {
                        DeviceConnFactoryManager.getDeviceConnFactoryManager().closePort();
                        Utils.toast(BlueToothTestMainActivity.this, getString(R.string.str_disconnect_success));
                    }
                    break;
                case PRINTER_COMMAND_ERROR:
                    Utils.toast(BlueToothTestMainActivity.this, getString(R.string.str_choice_printer_command));
                    break;
                case CONN_PRINTER:
                    Utils.toast(BlueToothTestMainActivity.this, getString(R.string.str_cann_printer));
                    break;
            }
        }
    };

    @Override
    protected void onStop() {
        super.onStop();
        unregisterReceiver(receiver);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.e(TAG, "onDestroy()");
        if (isConnected()) {
            DeviceConnFactoryManager.getDeviceConnFactoryManager().closePort();
        }
        if (threadPool != null) {
            threadPool.stopThreadPool();
        }
    }

    private String getConnDeviceInfo() {
        String str = "";
        if (isConnected()) {
            if (DeviceConnFactoryManager.getDeviceConnFactoryManager().getConnMethod() == DeviceConnFactoryManager.CONN_METHOD.BLUETOOTH) {
                str += "BLUETOOTH\n";
                str += "MacAddress: " + DeviceConnFactoryManager.getDeviceConnFactoryManager().getMacAddress();
            } else if (DeviceConnFactoryManager.getDeviceConnFactoryManager().getConnMethod() == DeviceConnFactoryManager.CONN_METHOD.WIFI) {
                str += "WIFI\n";
                str += "IP: " + DeviceConnFactoryManager.getDeviceConnFactoryManager().getIp() + "\n";
                str += "Port: " + DeviceConnFactoryManager.getDeviceConnFactoryManager().getPort();
            }
        }
        return str;
    }

    private boolean isConnected() {
        return DeviceConnFactoryManager.getDeviceConnFactoryManager() != null && DeviceConnFactoryManager.getDeviceConnFactoryManager().getConnState();
    }

}